package rtda

/**
 * Java虚拟机栈又由栈帧（Stack Frame，后面简称帧）构成，
 * 帧中保存方法执行的状态，包括局部变量表（Local Variable）
 * 和操作数栈（Operand Stack）等
 *
 * maxSize 栈的容量
 * size 当前栈的大小
 */
type Stack struct {
	maxSize uint
	size    uint
	_top    *Frame
}

func newStack(maxSize uint) *Stack {
	return &Stack{
		maxSize: maxSize,
	}
}

/**
 * 入栈，成为栈顶
 */
func (self *Stack) push(frame *Frame) {
	if self.size >= self.maxSize {
		panic("java.lang.StackOverflowError")
	}
	if self._top != nil {
		frame.lower = self._top
	}
	self._top = frame
	self.size++
}

/**
 * 返回栈顶
 */
func (self *Stack) pop() *Frame {
	if self._top == nil {
		panic("jvm stack is empty!")
	}
	// 返回栈顶并将栈顶的下一个节点设置为新的栈顶
	top := self._top
	self._top = top.lower
	top.lower = nil
	self.size--
	return top
}

/**
 * 查看栈顶
 */
func (self *Stack) top() *Frame {
	if self._top == nil {
		panic("jvm stack is empty!")
	}
	return self._top
}

func (self *Stack) getFrames() []*Frame {
	frames := make([]*Frame, 0, self.size)
	for frame := self._top; frame != nil; frame = frame.lower {
		frames = append(frames, frame)
	}
	return frames
}

func (self *Stack) isEmpty() bool {
	return self._top == nil
}

func (self *Stack) Size() uint {
	return self.size
}

func (self *Stack) clear() {
	for !self.isEmpty() {
		self.pop()
	}
}
